//----------------------------------Include-------------------------------------
#include "mcu.h"
//------------------------------------------------------------------------------

//起始地址      结束地址      地址空间   名称                 描述
//0x00000000   0x0003FFFF   256 KB    ILM                  指令本地存储器
//0x00020000   0x000BFFFF   256 KB    DLM                  数据指令本地存储器
//0x000C0000   0x000C00BF    192 B    FGPIO                快速 GPIO 控制器
//0x01000000   0x0103FFFF   256 KB    CPU0_ILM_SLV         CPU0 ILM 镜像
//0x01040000   0x0107FFFF   256 KB    CPU0_DLM_SLV         CPU0 DLM 镜像
//0x01080000   0x010FFFFF   512 KB    XRAM0                AXI SRAM0
//0x01100000   0x0117FFFF   512 KB    XRAM1                AXI SRAM1
//0x01180000   0x011BFFFF   256 KB    CPU1_ILM_SLV         CPU1 ILM 镜像
//0x011C0000   0x011FFFFF   256 KB    CPU1_DLM_SLV         CPU1 DLM 镜像
//
//0x20000000   0x2001FFFF   128 KB    ROM                  只读存储器 ROM
//0x30000000   0x300FFFFF     1 MB    DM                   DEBUG 调试模块
//
//0x40000000   0x4FFFFFFF   256 MB    FEMC                 FEMC 存储空间
//0x80000000   0x8FEFFFFF   255 MB    XPI0                 串行总线控制器 XPI0 存储空间
//0x90000000   0x9FEFFFFF   255 MB    XPI1                 串行总线控制器 XPI1 存储空间
//
//0xE4000000   0xE43FFFFF     4 MB    PLIC                 平台中断控制器 PLIC
//0xE6000000   0xE60FFFFF     1 MB    MCHTMR               机器定时器
//0xE6400000   0xE67FFFFF     4 MB    PLICSW               平台软件中断控制器
//
//0xF0000000 及之后 外设
//0xF0300000   0xF0307FFF    32 KB    HRAM                 AHB SRAM
//
//0xF40F0000   0xF40F1FFF     8 KB    PMIC_MEM             APB SRAM

//------------------------------------------------------------------------------
#if 1
/**
 * @brief FLASH configuration option definitions:
 * option[0]:
 *    [31:16] 0xfcf9 - FLASH configuration option tag
 *    [15:4]  0 - Reserved
 *    [3:0]   option words (exclude option[0])
 *
 * option[1]:
 *    [31:28] Flash probe type
 *      0 - SFDP SDR / 1 - SFDP DDR
 *      2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
 *      4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
 *      6 - OctaBus DDR (SPI -> OPI DDR)
 *      8 - Xccela DDR (SPI -> OPI DDR)
 *      10 - EcoXiP DDR (SPI -> OPI DDR)
 *    [27:24] Command Pads after Power-on Reset
 *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
 *    [23:20] Command Pads after Configuring FLASH
 *      0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
 *    [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
 *      0 - Not needed
 *      1 - QE bit is at bit 6 in Status Register 1
 *      2 - QE bit is at bit1 in Status Register 2
 *      3 - QE bit is at bit7 in Status Register 2
 *      4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
 *    [15:8] Dummy cycles
 *      0 - Auto-probed / detected / default value
 *      Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
 *    [7:4] Misc.
 *      0 - Not used
 *      1 - SPI mode
 *      2 - Internal loopback
 *      3 - External DQS
 *    [3:0] Frequency option
 *      1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
 *
 * option[2] (Effective only if the bit[3:0] in option[0] > 1)
 *    [31:20]  Reserved
 *    [19:16] IO voltage
 *      0 - 3V / 1 - 1.8V
 *    [15:12] Pin group
 *      0 - 1st group / 1 - 2nd group
 *    [11:8] Connection selection
 *      0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
 *    [7:0] Drive Strength
 *      0 - Default value
 *
 * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
 *              JESD216)
 *    [31:16] reserved
 *    [15:12] Sector Erase Command Option, not required here
 *    [11:8]  Sector Size Option, not required here
 *    [7:0] Flash Size Option
 *      0 - 4MB / 1 - 8MB / 2 - 16MB
 */
#if defined(FLASH_XIP) && FLASH_XIP
__attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90002, 0x00000007, 0xE, 0x0};
#endif

#if defined(FLASH_UF2) && FLASH_UF2
ATTR_PLACE_AT(".uf2_signature") const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;
#endif

#endif
//-----------------------------------Macro--------------------------------------
//------------------------------------------------------------------------------

//--------------------------------Static Var------------------------------------
//------------------------------------------------------------------------------

//--------------------------------Static Func-----------------------------------
//------------------------------------------------------------------------------

//--------------------------------Public Func-----------------------------------
void mcu_int_disable(void)      { disable_global_irq(CSR_MSTATUS_MIE_MASK);   }
void mcu_int_enable(void)       { enable_global_irq(CSR_MSTATUS_MIE_MASK);    }
void mcu_reset(void)            { }
void mcu_nop(void)              { }
//------------------------------------------------------------------------------
void mcu_init_pmp(void)
{
  uint32_t start_addr;
  uint32_t end_addr;
  uint32_t length;
  pmp_entry_t pmp_entry[16];
  uint8_t index = 0;

  /* Init noncachable memory */
  extern uint32_t __noncacheable_start__[];
  extern uint32_t __noncacheable_end__[];
  start_addr = (uint32_t)__noncacheable_start__;
  end_addr   = (uint32_t)__noncacheable_end__;
  length     = end_addr - start_addr;
  if (length > 0) {
    /* Ensure the address and the length are power of 2 aligned */
    assert((length & (length - 1U)) == 0U);
    assert((start_addr & (length - 1U)) == 0U);
    pmp_entry[index].pmp_addr    = PMP_NAPOT_ADDR(start_addr, length);
    pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
    pmp_entry[index].pma_addr    = PMA_NAPOT_ADDR(start_addr, length);
    pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
    index++;
  }

  /* Init share memory */
  extern uint32_t __share_mem_start__[];
  extern uint32_t __share_mem_end__[];
  start_addr = (uint32_t)__share_mem_start__;
  end_addr   = (uint32_t)__share_mem_end__;
  length     = end_addr - start_addr;
  if (length > 0) {
    /* Ensure the address and the length are power of 2 aligned */
    assert((length & (length - 1U)) == 0U);
    assert((start_addr & (length - 1U)) == 0U);
    pmp_entry[index].pmp_addr    = PMP_NAPOT_ADDR(start_addr, length);
    pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
    pmp_entry[index].pma_addr    = PMA_NAPOT_ADDR(start_addr, length);
    pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
    index++;
  }

  pmp_config(&pmp_entry[0], index);
}
//------------------------------------EOF---------------------------------------





